/**
 * Package:com.sofmit.supercity.server.chat;
 * $Id: ProtocolBinaryHandler.java,v 1.5 2009/03/28 08:57:13 yangc Exp $
 * Copyright(c) 2001-2005 www.afteryuan.com
 */
package com.afteryuan.server.mina;

import com.afteryuan.server.ConnectSession;
import com.afteryuan.server.SpringContextLoader;
import com.afteryuan.server.data.Sprite;
import com.afteryuan.server.data.SpritePool;
import com.afteryuan.server.handler.SpringHanlderDispatcher;
import com.afteryuan.server.service.SpriteService;
import com.afteryuan.server.command.down.core.QuitRoomDown;
import com.afteryuan.server.command.up.CommandUp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IdleStatus;

import java.io.IOException;

/**
 * ProtocolBinaryHandler类 消息处理类<br/>
 * 处理socket连接各种事件
 * <p/>
 * <p><a href="ProtocolBinaryHandler.java.html"><i>View Source</i></a></p>
 *
 * @author <a href="mailto:afteryuan@afteryuan.com">$Author: yangc $</a>
 * @version $Revision: 1.5 $
 */
public class ProtocolBinaryHandler extends IoHandlerAdapter {
    private static Log log = LogFactory.getLog(ProtocolBinaryHandler.class);


    /**
     * 消息到达时处理方法，根据消息内容不同，调用具体的hanlder处理上传的命令
     *
     * @param ioSession socket连接会话
     * @param o         到达的消息对象
     * @throws Exception
     */
    public void messageReceived(IoSession ioSession, Object o) throws Exception {
            ConnectSession session = new MinaConnectSession(ioSession);
            SpringHanlderDispatcher.doDispath(session, (CommandUp) o);
    }

    /**
     * 当socket连接抛出异常时处理
     *
     * @param ioSession socket连接会话
     * @param throwable 抛出的异常
     * @throws Exception
     */
    public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception {
        if(throwable instanceof IOException ){
        sessionClosed(ioSession);
        }
    }

    /**
     * 有客户端打开一个socket连接时调用，报告某个IP连接上了服务器
     *
     * @param ioSession socket连接会话
     * @throws Exception
     */
    public void sessionOpened(IoSession ioSession) throws Exception {
//        ioSession.getConfig().setIdleTime(IdleStatus.READER_IDLE,30);//设置读取超时30秒
//        super.sessionOpened(ioSession);
        log.debug("客户端" + ioSession.getRemoteAddress() + "打开了一个连接");
    }

    /**
     * socket连接被断开时调用，报告某个IP断开了连接。
     *
     * @param ioSession socket连接会话
     * @throws Exception
     */
    public void sessionClosed(IoSession ioSession) throws Exception {
            log.warn("connect is close");
            Sprite sprite = (Sprite) ioSession.getAttribute(Sprite.KEY_SPRITE_ID);
            SpritePool spritePool = (SpritePool) SpringContextLoader.getInstance().getBeanFactory().getBean("spritePool");
            
            SpriteService spriteService = (SpriteService)SpringContextLoader.getInstance().getBeanFactory().getBean("spriteService");
            QuitRoomDown quit = new QuitRoomDown();
            quit.avatarId = sprite.getId();
            spriteService.broadcast(sprite.getRoom(),quit);
            
            spritePool.removeFromRoom(sprite.getRoom(),sprite.getId());
            spritePool.removeFromServer(sprite.getId());
            spritePool.addToGhost(sprite);
            
    }

    /**
     * socket连接被建立时调用
     *
     * @param ioSession socket连接会话
     * @throws Exception
     */
    public void sessionCreated(IoSession ioSession) throws Exception {
        super.sessionCreated(ioSession);
//        log.debug("session is created!");

    }

    /**
     * ioSession处理空闲状态时调用
     *
     * @param ioSession  socket连接会话
     * @param idleStatus 空闲状态
     * @throws Exception
     */
    public void sessionIdle(IoSession ioSession, IdleStatus idleStatus) throws Exception {
//        super.sessionIdle(ioSession, idleStatus);
//        log.debug("session is idle!");

    }

    /**
     * 消息被发送成功完成时调用
     *
     * @param ioSession socket连接会话
     * @param o         发送完成的消息对象
     * @throws Exception
     */
    public void messageSent(IoSession ioSession, Object o) throws Exception {
        super.messageSent(ioSession, o);
//        log.debug("message " + o + " is sent!");

    }
}